package data

import (
	"context"
	"helloworld/app/user/service/internal/conf"

	"github.com/go-kratos/kratos/v2/log"
	_ "github.com/go-sql-driver/mysql"
	"github.com/google/wire"
	amqp "github.com/rabbitmq/amqp091-go"
	"github.com/redis/go-redis/v9"
	"go.mongodb.org/mongo-driver/mongo"
	"gorm.io/gorm"
)

// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewUserRepo, NewMysql, NewMongo, NewRedis, NewMq)

// Data .
type Data struct {
	// TODO wrapped database client
	mysql *gorm.DB
	mongo *mongo.Client
	redis *redis.Client
	mq    *amqp.Connection
}

// NewData .
func NewData(c *conf.Data, logger log.Logger, mysql *gorm.DB, mongo *mongo.Client, redis *redis.Client, mq *amqp.Connection) (*Data, func(), error) {
	d := &Data{
		mysql: mysql,
		mongo: mongo,
		redis: redis,
		mq:    mq,
	}
	cleanup := func() {
		log.NewHelper(logger).Info("closing the data resources")
		sqldb, err := d.mysql.DB()
		if err != nil {
			log.Errorf("sqldb resource got fail: %v", err)
		}
		if err := sqldb.Close(); err != nil {
			log.Errorf("sqldb closing resource got fail: %v", err)
		}
		if err := d.mongo.Disconnect(context.TODO()); err != nil {
			log.Errorf("mongo closing resource got fail: %v", err)
		}
		if err := d.redis.Close(); err != nil {
			log.Errorf("redis closing resource got fail: %v", err)
		}
		if err := d.mq.Close(); err != nil {
			log.Errorf("mq closing resource got fail: %v", err)
		}

	}
	return d, cleanup, nil
}
